<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>虚幻引擎程序设计浅析 | Abel&#39;Blog</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="开一篇文章记录学习Unreal Engine相关知识。参考《虚幻引擎程序设计浅析》ISBN 978-7-121-31349-3，电子工业出版社。带着问题来学习，才能学的快速。看书先需要阅读的就是作者划分的章节目录，反复多看几遍，能从总体上看出知识的结构。 第一部分 虚幻引擎C++编程第1章 五个类的熟悉最首先了解5个类，比较关键。 UObject Actor Pawn Controller Cha">
<meta property="og:type" content="article">
<meta property="og:title" content="虚幻引擎程序设计浅析">
<meta property="og:url" content="http://example.com/2021/07/28/2021/2021-01-14-UnrealEngine4/index.html">
<meta property="og:site_name" content="Abel&#39;Blog">
<meta property="og:description" content="开一篇文章记录学习Unreal Engine相关知识。参考《虚幻引擎程序设计浅析》ISBN 978-7-121-31349-3，电子工业出版社。带着问题来学习，才能学的快速。看书先需要阅读的就是作者划分的章节目录，反复多看几遍，能从总体上看出知识的结构。 第一部分 虚幻引擎C++编程第1章 五个类的熟悉最首先了解5个类，比较关键。 UObject Actor Pawn Controller Cha">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2021-07-28T03:33:01.236Z">
<meta property="article:modified_time" content="2021-04-08T13:14:14.138Z">
<meta property="article:author" content="Abel Sean">
<meta property="article:tag" content="Game">
<meta property="article:tag" content="Unreal Engine4">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/atom.xml" title="Abel&#39;Blog" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  
<link rel="stylesheet" href="/css/style.css">

<meta name="generator" content="Hexo 5.4.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">Abel&#39;Blog</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://example.com"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main"><article id="post-2021/2021-01-14-UnrealEngine4" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2021/07/28/2021/2021-01-14-UnrealEngine4/" class="article-date">
  <time datetime="2021-07-28T03:33:01.236Z" itemprop="datePublished">2021-07-28</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      虚幻引擎程序设计浅析
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>开一篇文章记录学习Unreal Engine相关知识。参考《虚幻引擎程序设计浅析》ISBN 978-7-121-31349-3，电子工业出版社。带着问题来学习，才能学的快速。看书先需要阅读的就是作者划分的章节目录，反复多看几遍，能从总体上看出知识的结构。</p>
<h1 id="第一部分-虚幻引擎C-编程"><a href="#第一部分-虚幻引擎C-编程" class="headerlink" title="第一部分 虚幻引擎C++编程"></a>第一部分 虚幻引擎C++编程</h1><h2 id="第1章-五个类的熟悉"><a href="#第1章-五个类的熟悉" class="headerlink" title="第1章 五个类的熟悉"></a>第1章 五个类的熟悉</h2><p>最首先了解5个类，比较关键。</p>
<p>UObject Actor Pawn Controller Character</p>
<ol>
<li>UObject</li>
</ol>
<p>提供垃圾回收</p>
<p>这个功能和c++标准中的智能指针是冲突的。</p>
<p>反射</p>
<p>相当于实现了java、c#中的反射功能。在本书的第二部分解释了。</p>
<p>序列化</p>
<p>提供无损的加载，序列化方便保存到磁盘或者传递给远端服务器。</p>
<p>与虚幻引擎编辑器的交互</p>
<p>可以在Editor面板里面方便的使用。</p>
<p>运行时类型识别</p>
<p>这个功能也会和C++标准中的RTTI机制：dynamic_cast有冲突。一旦使用，要使用Cast&lt;&gt;函数做类型转换。虚幻号称会提供更加高效的类型识别。</p>
<p>网络复制</p>
<p>在c/s架构中，其被宏标记的变量能够自动完成网络复制。从服务器端复制对应值到客户端。</p>
<ol start="2">
<li>Actor</li>
</ol>
<p>它能被挂载组件Component。</p>
<p>UE中的Component和unity的是很大的不同。在虚幻里面，Component含义被极大削弱。</p>
<ol start="3">
<li>灵魂与肉体：Pawn、Character和Controller</li>
</ol>
<p>Pawn类是提供被操控的特性。它能被Controller操控，Controller可以是用户输入或者AI。Pawn离开操控者无法自主行动的肉体。</p>
<p>Character继承于Pawn。提供了特殊组件，Character Movement组件。提供基础的、基于胶囊体的角色移动，跳跃之类的。</p>
<p>Controller</p>
<p>操控肉体的类，肉体拥有前行、转向、跳跃、开火等函数。类似MVC设计模式。Controller就是管理器，Pawn就是Model，而Pawn挂载的动态网格组件就是View。这个例子也不算太合适能初略建立概念。</p>
<h2 id="第2章-需求到实现"><a href="#第2章-需求到实现" class="headerlink" title="第2章 需求到实现"></a>第2章 需求到实现</h2><ol>
<li>分析需求</li>
</ol>
<p>使用UML工程建模工具绘制需求分析图。</p>
<p>或者通过沟通分析出来简短的短语。</p>
<ol start="2">
<li>转化需求为设计</li>
</ol>
<p>首先从短语中抽象出里面重要的名词，这样就是我们的类。</p>
<p>然后分析出类之间的持有、通信关系。</p>
<h2 id="第3章-创建自己的C-类"><a href="#第3章-创建自己的C-类" class="headerlink" title="第3章 创建自己的C++类"></a>第3章 创建自己的C++类</h2><ol>
<li>使用Unreal Editor创建c++类</li>
</ol>
<p>“内容浏览器” -&gt; “右键” -&gt; “新建C++类”</p>
<p>有一个创建的流程，可以在过程中选择基类。输入名称选择路径。</p>
<ol start="2">
<li>手动创建C++类</li>
</ol>
<p>文件目录结构为</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">--public/</span><br><span class="line">--private/</span><br><span class="line">--.build.cs</span><br></pre></td></tr></table></figure>

<p>头文件放到public文件夹，cpp放入private文件夹。</p>
<p>如果继承了UE的类，需要增加一些宏，否则编译不过。</p>
<p>cpp文件中包含pch文件。</p>
<ol start="3">
<li>虚幻引擎类命名规则</li>
</ol>
<blockquote>
<p>F 纯C++类<br>U 继承自UObject，但不继承Actor<br>A 继承自Actor<br>S Slate控件相关类<br>H HitResult相关类</p>
</blockquote>
<p>Unreal Header Tool 会在编译之前检查这些类名的约束。</p>
<h2 id="第4章-对象"><a href="#第4章-对象" class="headerlink" title="第4章 对象"></a>第4章 对象</h2><ol>
<li>类对象的产生</li>
</ol>
<p>如果是纯C++类型，可以通过new产生。</p>
<p>如果你的类继承自UObject，需要通过NewObject函数来产生。</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">NewObject&lt;T&gt;();</span><br></pre></td></tr></table></figure>

<p>如果继承自AActor，需要通过SpawnActor函数产生对象。</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">GetWorld</span>()-&gt;SpawnActor&lt;AYourActorClass&gt;();</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>类对象的获取</li>
</ol>
<p>通过对象的引用或者指针来获取。GetWorld能使用IActorIterator<AACtor>迭代World里面全部的Actor。</p>
<ol start="3">
<li>类对象的销毁</li>
</ol>
<p>纯C++类型，就是自己delete就可以了。</p>
<p>UObject的对象，本身有一套内存管理机制，当没有对象引用了，就会触发GC。</p>
<p>Actor的对象，通过Destory函数请求销毁，这个只是说从World里面摘除掉，内存回收还需要靠引擎来决定。</p>
<h2 id="第5章-从C-到蓝图"><a href="#第5章-从C-到蓝图" class="headerlink" title="第5章 从C++到蓝图"></a>第5章 从C++到蓝图</h2><p>让蓝图调用我的C++类。</p>
<ol>
<li>UPROPERTY宏</li>
</ol>
<p>将成员变量注册到蓝图中。</p>
<ol start="2">
<li>UFUNCTION宏</li>
</ol>
<p>注册函数到蓝图中。</p>
<h2 id="第6章-游戏性框架概述"><a href="#第6章-游戏性框架概述" class="headerlink" title="第6章 游戏性框架概述"></a>第6章 游戏性框架概述</h2><h3 id="1-行为树：概念与原理"><a href="#1-行为树：概念与原理" class="headerlink" title="1. 行为树：概念与原理"></a>1. 行为树：概念与原理</h3><ol>
<li>为什么选择行为树</li>
</ol>
<p>ue3框架是状态机制作的，还引入了Unreal Script脚本来扩展。在ue4直接被行为树系统替换。状态机只在动画蓝图中保留。</p>
<p>粗俗来说，行为树特点：“逐个尝试，不行就换”的思路。更加符合人的思维方式。</p>
<ol start="2">
<li>行为树原理</li>
</ol>
<p>三种节点：</p>
<blockquote>
<p>流程控制：包含Selector选择器和Sequence顺序执行器。<br>装饰器：对子树的返回值进行处理的节点。<br>执行节点：干活的节点，返回trun或者false，running。</p>
</blockquote>
<p>可以参考之前写过的行为树的文档，里面也有if语句，&amp;&amp;||的逻辑运算，挂起唤醒逻辑，循环逻辑等等。是一种使用可视化方式提供给别人来编写程序的一种方法。</p>
<h3 id="2-虚幻引擎网络框架构"><a href="#2-虚幻引擎网络框架构" class="headerlink" title="2. 虚幻引擎网络框架构"></a>2. 虚幻引擎网络框架构</h3><ol>
<li>同步</li>
</ol>
<p>多人在线的同步问题，是通过一台<em>权威服务器</em>来负责将数据收集起来，并且分发给客户端。让作弊变得困难。</p>
<blockquote>
<p>指令：对于游戏世界造成影响的请求。egg：人物前移3米，人物挥刀碰到了怪物<br>状态：游戏世界的各种数值状态。egg：当前人物生命值，当前怪物生命值。</p>
</blockquote>
<p>客户端只能向服务器发送“指令”，服务器根据指令处理之后，改变游戏世界的状态，并且将状态<em>同步</em>给每个客户端。</p>
<ol start="2">
<li>广义的客户端-服务器模型</li>
</ol>
<blockquote>
<p>客户端是对服务器的拙劣模仿 — 虚幻官方文档UDN中描述<br>“拙劣”二字，表示是服务器的世界是正确的，而客户端则是不断试图猜测服务器当前的状态，并且模仿。</p>
</blockquote>
<h2 id="第7章-引擎系统相关类"><a href="#第7章-引擎系统相关类" class="headerlink" title="第7章 引擎系统相关类"></a>第7章 引擎系统相关类</h2><p>本章主要介绍一些虚幻引擎4提供的一些类，防止程序重复造轮子。</p>
<h3 id="7-1-正则表达式"><a href="#7-1-正则表达式" class="headerlink" title="7.1 正则表达式"></a>7.1 正则表达式</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;Regex.h&quot;</span></span></span><br><span class="line"><span class="function">FString <span class="title">TextStr</span><span class="params">(<span class="string">&quot;AAAABBBBB&quot;</span>)</span></span>;</span><br><span class="line"><span class="function">FRegexPattern <span class="title">TestPattern</span><span class="params">(TEXT(<span class="string">&quot;C.+H&quot;</span>))</span></span>;</span><br><span class="line">FRegexMatcher xxx;</span><br></pre></td></tr></table></figure>

<p><a target="_blank" rel="noopener" href="https://docs.unrealengine.com/en-US/API/Runtime/Core/Internationalization/FRegexPattern/index.html">FRegexPattern手册</a></p>
<p>基本上能满足匹配，抓取之类的操作。</p>
<h3 id="7-2-FPaths"><a href="#7-2-FPaths" class="headerlink" title="7.2 FPaths"></a>7.2 FPaths</h3><p>获取游戏的根目录；判断文件是否存在；路径转换成绝对路径类似的功能。</p>
<p><a target="_blank" rel="noopener" href="https://docs.unrealengine.com/en-US/API/Runtime/Core/Misc/FPaths/index.html">FPaths官方文档</a></p>
<h3 id="7-3-XML-JSON"><a href="#7-3-XML-JSON" class="headerlink" title="7.3 XML/JSON"></a>7.3 XML/JSON</h3><p>FXmlFile/FastXML访问XML数据；</p>
<p>TJsonReaderFactory<TCHAR>/TJsonReader<TCHAR></p>
<p>FJsonSerializer::Deserialize 来加载json字符串。</p>
<h3 id="7-4-文件读写与访问"><a href="#7-4-文件读写与访问" class="headerlink" title="7.4 文件读写与访问"></a>7.4 文件读写与访问</h3><p>PlatformFileManager.h</p>
<p>里面提供了很多的操作文件的接口。</p>
<h3 id="7-5-GConfig"><a href="#7-5-GConfig" class="headerlink" title="7.5 GConfig"></a>7.5 GConfig</h3><p>是简单的将ini文件做了封装。可以指定ini文件，Section名称，Key，值。</p>
<h3 id="7-6-UE-LOG"><a href="#7-6-UE-LOG" class="headerlink" title="7.6 UE_LOG"></a>7.6 UE_LOG</h3><p>能支持Category方式的日志输出，日志级别也能支持。</p>
<h3 id="7-7-字符串处理"><a href="#7-7-字符串处理" class="headerlink" title="7.7 字符串处理"></a>7.7 字符串处理</h3><p>FName 无法修改的字符串，大小写不敏感。无论出现多少次，都是在字符串表里面只有一次出现。访问速度将会很快速。</p>
<p>FText 用于做显示的字符串，内置了本地化。</p>
<p>FString 能支持修改，消耗比上述的两种都要大。</p>
<h3 id="7-8-编译器相关技巧"><a href="#7-8-编译器相关技巧" class="headerlink" title="7.8 编译器相关技巧"></a>7.8 编译器相关技巧</h3><h4 id="7-8-1-废弃函数标记"><a href="#7-8-1-废弃函数标记" class="headerlink" title="7.8.1 废弃函数标记"></a>7.8.1 废弃函数标记</h4><p>编译器会检测出一些警告。</p>
<p>function Please update youre code to the new API before upgrading to the next release, otherwise your project will no longer compile.</p>
<h4 id="7-8-2-编译器指令实现跨平台"><a href="#7-8-2-编译器指令实现跨平台" class="headerlink" title="7.8.2 编译器指令实现跨平台"></a>7.8.2 编译器指令实现跨平台</h4><p>虚幻提供了FPlatformMisc，包含了大量平台相关的工具函数。</p>
<p>通过 typedef 切换编译期的平台切换。</p>
<p>在Linux里面有 FLinuxPlatformMisc 。切换的时候，将写这样的一句话。</p>
<p>typedef FLinuxPlatformMisc FPlatformMisc。</p>
<h3 id="7-9-Images"><a href="#7-9-Images" class="headerlink" title="7.9 Images"></a>7.9 Images</h3><p>ImagerWrapper 图片类型的抽象。</p>
<p>包含完整RGBA(red green blue alpha)数据的图片，是没有压缩过的，和格式没有关系，称为RawData原生的数据。</p>
<p>CompressedData会随着图片格式不同而不同。</p>
<p>ImagerWrapper是对这两个的封装。</p>
<h1 id="第二部分-虚幻引擎浅析"><a href="#第二部分-虚幻引擎浅析" class="headerlink" title="第二部分 虚幻引擎浅析"></a>第二部分 虚幻引擎浅析</h1><h2 id="第8章-模块机制"><a href="#第8章-模块机制" class="headerlink" title="第8章 模块机制"></a>第8章 模块机制</h2><h3 id="8-1-模块简介"><a href="#8-1-模块简介" class="headerlink" title="8.1 模块简介"></a>8.1 模块简介</h3><p>C++项目对外提供库的时候，需要管理include,lib目录。Debug/Release模式下的lib文件的管理。而且还需要编译不同平台下的库文件。</p>
<p>在UE3的时候，使用MakeFile来模拟模块，UE4为了彻底解决这些问题，使用了Unreal Build Tool。</p>
<h3 id="8-2-创建自己的模块"><a href="#8-2-创建自己的模块" class="headerlink" title="8.2 创建自己的模块"></a>8.2 创建自己的模块</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">模块名.Build.cs</span><br><span class="line">模块名.h</span><br><span class="line">模块名.cpp</span><br></pre></td></tr></table></figure>

<p>引入模块</p>
<p>工程名.Target.cs</p>
<p>SetupBinaries 方法里面调用 AddRange 函数将模块引入。</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">OutExtraModuleNames.<span class="built_in">AddRange</span>( <span class="keyword">new</span> string[]&#123;</span><br><span class="line">  <span class="string">&quot;pluginDev&quot;</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<p>插件名.uplugin</p>
<p>文件里面写了关于插件相关的信息。文件格式是json。</p>
<h3 id="8-3-虚幻引擎初始化模块加载顺序"><a href="#8-3-虚幻引擎初始化模块加载顺序" class="headerlink" title="8.3 虚幻引擎初始化模块加载顺序"></a>8.3 虚幻引擎初始化模块加载顺序</h3><p>本章就是列举了加载各种模块的顺序。</p>
<h3 id="8-4-UBT-UHT"><a href="#8-4-UBT-UHT" class="headerlink" title="8.4 UBT/UHT"></a>8.4 UBT/UHT</h3><p>UBT=Unreal Build Tool</p>
<p>UBT工作分为三个阶段：</p>
<ol>
<li>收集阶段，将环境变量、UE源码目录，工程目录信息收集起来；</li>
<li>参数解析阶段，将传入的命令行参数，确定自己生成的目标类型；</li>
<li>实际生成阶段，根据环境、参数，开始生成makefile，确定C++的各种目录位置。开始构建项目。</li>
</ol>
<p>UHT=Unreal Header Tool</p>
<p>UHT 配合实现了反射机制。</p>
<h2 id="第9章-重要合行系统简介"><a href="#第9章-重要合行系统简介" class="headerlink" title="第9章 重要合行系统简介"></a>第9章 重要合行系统简介</h2><h3 id="9-1-内存分配"><a href="#9-1-内存分配" class="headerlink" title="9.1 内存分配"></a>9.1 内存分配</h3><h4 id="9-1-1-Windows操作系统下的内存分配方案"><a href="#9-1-1-Windows操作系统下的内存分配方案" class="headerlink" title="9.1.1 Windows操作系统下的内存分配方案"></a>9.1.1 Windows操作系统下的内存分配方案</h4><p>主要通过</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">FMalloc* <span class="title">FWindowsPlatformMemory::BaseAllocator</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span></span><br><span class="line"><span class="function"><span class="meta">#<span class="meta-keyword">if</span> ENABLE_WIN_ALLOC_TRACKING</span></span></span><br><span class="line"><span class="function"><span class="meta">#<span class="meta-keyword">if</span> FORCE_ANSI_ALLOCATOR</span></span></span><br><span class="line"><span class="function"><span class="meta">#<span class="meta-keyword">elif</span> WITH_EDITORONLY_DATA </span></span></span><br></pre></td></tr></table></figure>

<p>一共提供了Mallo（ANSI）、Intel TBB，以及Binned内存分配器。</p>
<h3 id="9-2-引擎初始化过程"><a href="#9-2-引擎初始化过程" class="headerlink" title="9.2 引擎初始化过程"></a>9.2 引擎初始化过程</h3><p>初始化过程一共两个</p>
<p>PreInit/Init</p>
<p>PreInit支持输出参数，CmdLine。</p>
<p>设置好工作目录，游戏目录。</p>
<p>初始化随机种子。</p>
<p>设置输出标准设备。</p>
<p>初始游戏主线程。</p>
<p>会调用LoadCoreModules。CoreModules。</p>
<p>之后会将PreInitModules会被加载起来，启动之后调用AppInit函数。</p>
<p>Init</p>
<p>所有模块都加载到内存中，如果有PostEngineInit函数，就会调用。过程由IProjectManager完成。</p>
<p>主循环</p>
<p>虚幻引擎，有一个EngineTick()。在主循环中最好不要调用繁重的任务，否则将会把游戏卡住。</p>
<h3 id="9-3-并行与并发"><a href="#9-3-并行与并发" class="headerlink" title="9.3 并行与并发"></a>9.3 并行与并发</h3><p>测试代码一般文件名称为<code>模块名Test.cpp</code>。</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">DEFINE_LOG_CATEGORY_STATIC</span>(TestLog,Log,All);</span><br><span class="line"><span class="built_in">IMPLEMENT_SIMPLE_AUTOMATION_TEST</span>(FMultiThreadTest,<span class="string">&quot;MyTest.PublicTest</span></span><br><span class="line"><span class="string">  .MultiThreadIest&quot;</span>, EAutomationTestFlags::EditorContext |</span><br><span class="line">  EAutomationTestFlags::EngineFilter)</span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">FMultiThreadTest::RunTest</span><span class="params">(<span class="keyword">const</span> FString&amp; Parameters)</span></span></span><br></pre></td></tr></table></figure>

<p>通过UE4菜单栏。</p>
<p>Windows -&gt; General -&gt; Developer Tools -&gt; Session Frontend</p>
<p>打开“会话窗口”。</p>
<p>点击”Start Tests”按钮，就可以在Message Output里面输出的日志。</p>
<p>可以通过<code>FRunnableThread::Create(new FRunnableTestThread(0)</code>创建线程。就能开启多个线程。</p>
<p>Task Graph系统</p>
<p>将“指令”和“数据”封成一个包，然后交给Task Graph，Task Graph找到空闲的线程，去处理Task。</p>
<p>虚幻引擎Rama，写过对于Task Graph的描述。</p>
<p>Task Graph采用模板匹配，无需每个Task继承于指定的类，只要类将一些函数实现，就能让模板编译通过。<code>TGraphTask::CreateTask</code>。</p>
<p>std::thread</p>
<p>可以直接使用c++11的多线程。</p>
<p>线程同步</p>
<p>灵界区<code>FCriticalSection</code>。</p>
<p>也提供了<code>std::future</code>，<code>std::promise</code>,<code>TFuture</code>, <code>TPromise</code>。</p>
<p>多进程</p>
<p><code>Core.GenericPlatformProcess</code>可以看到<code>FGenericPlatformProcess</code>类的定义。可以通过管道进行数据交换。也将会返回<code>FProcHandle</code>子进程的句柄。</p>
<h2 id="第10章-对象模型"><a href="#第10章-对象模型" class="headerlink" title="第10章 对象模型"></a>第10章 对象模型</h2><p>本章主要讨论 UObject对象、组件对象和Actor对象。</p>
<h3 id="10-1-UObject"><a href="#10-1-UObject" class="headerlink" title="10.1 UObject"></a>10.1 UObject</h3><p>创建：通过<code>NewObject&lt;T&gt;</code>产生。<br>销毁：通过引擎的垃圾回收来销毁。</p>
<p>创建过程分为两个步骤：</p>
<ol>
<li>通过分配器将内存分配出来；</li>
</ol>
<p>使用<code>UObjectGlobals.GetPropertiesSize()</code>获取目标类的内存大小；</p>
<p>使用<code>FUObjectAllocator.AllocateUObject()</code>分配内存；</p>
<ol start="2">
<li>使用这块内存调用new方法，构建对象出来；</li>
</ol>
<p>使用<code>PlacemenetNew</code>将分配好的内存区域调用UObjectBase构造函数</p>
<p>对<code>UObject</code>提供UPackage存储读取逻辑。成员变量没有使用<code>UPROPERTY</code>宏标记，将不会序列化。</p>
<h1 id="注册虚幻引擎阅读权限"><a href="#注册虚幻引擎阅读权限" class="headerlink" title="注册虚幻引擎阅读权限"></a>注册虚幻引擎阅读权限</h1><p>可以登录到UE官网，开通github中，开源的UE源码阅读权限。</p>
<h1 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h1><ul>
<li>[1] <a target="_blank" rel="noopener" href="https://docs.unrealengine.com/zh-CN/index.html">UnrealEngine4官方文档</a></li>
<li>[2] <a target="_blank" rel="noopener" href="https://space.bilibili.com/138827797?spm_id_from=333.788.b_765f7570696e666f.2">虚幻引擎官方-B站</a></li>
<li>[3] <a target="_blank" rel="noopener" href="https://www.zhihu.com/org/xu-huan-yin-qing-24">虚幻引擎-知乎</a></li>
<li>[4] <a target="_blank" rel="noopener" href="https://github.com/EpicGames/UnrealEngine">虚幻引擎github</a></li>
<li>[5] <a target="_blank" rel="noopener" href="https://blog.csdn.net/m0_38106923/article/details/101937827">图片格式列举</a></li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2021/07/28/2021/2021-01-14-UnrealEngine4/" data-id="ckrn3an7c001f20xw19ojch3u" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Game/" rel="tag">Game</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Unreal-Engine4/" rel="tag">Unreal Engine4</a></li></ul>

    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2021/07/28/2021/2021-01-22-%E7%BA%BF%E6%80%A7%E4%BB%A3%E6%95%B0/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          线性代数笔记
        
      </div>
    </a>
  
  
    <a href="/2021/07/28/2021/2021-01-11-vscode/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">vscode笔记</div>
    </a>
  
</nav>

  
</article>

</section>
        
          <aside id="sidebar">
  
    

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/tags/3D/" rel="tag">3D</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/AI/" rel="tag">AI</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/C/" rel="tag">C++</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Game/" rel="tag">Game</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Go/" rel="tag">Go</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Linux/" rel="tag">Linux</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Math/" rel="tag">Math</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Server/" rel="tag">Server</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Unreal-Engine4/" rel="tag">Unreal Engine4</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/git/" rel="tag">git</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/golang/" rel="tag">golang</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/guitar/" rel="tag">guitar</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/node-js/" rel="tag">node.js</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/protobuf/" rel="tag">protobuf</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/python/" rel="tag">python</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/recast/" rel="tag">recast</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/redis/" rel="tag">redis</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/type/" rel="tag">type</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/vscode/" rel="tag">vscode</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E8%BF%90%E7%BB%B4/" rel="tag">运维</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/tags/3D/" style="font-size: 10px;">3D</a> <a href="/tags/AI/" style="font-size: 11.67px;">AI</a> <a href="/tags/C/" style="font-size: 15px;">C++</a> <a href="/tags/Game/" style="font-size: 18.33px;">Game</a> <a href="/tags/Go/" style="font-size: 13.33px;">Go</a> <a href="/tags/Linux/" style="font-size: 13.33px;">Linux</a> <a href="/tags/Math/" style="font-size: 11.67px;">Math</a> <a href="/tags/Server/" style="font-size: 16.67px;">Server</a> <a href="/tags/Unreal-Engine4/" style="font-size: 10px;">Unreal Engine4</a> <a href="/tags/git/" style="font-size: 10px;">git</a> <a href="/tags/golang/" style="font-size: 20px;">golang</a> <a href="/tags/guitar/" style="font-size: 10px;">guitar</a> <a href="/tags/node-js/" style="font-size: 10px;">node.js</a> <a href="/tags/protobuf/" style="font-size: 10px;">protobuf</a> <a href="/tags/python/" style="font-size: 10px;">python</a> <a href="/tags/recast/" style="font-size: 11.67px;">recast</a> <a href="/tags/redis/" style="font-size: 10px;">redis</a> <a href="/tags/type/" style="font-size: 10px;">type</a> <a href="/tags/vscode/" style="font-size: 10px;">vscode</a> <a href="/tags/%E8%BF%90%E7%BB%B4/" style="font-size: 16.67px;">运维</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/07/">July 2021</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2021/07/28/2021/2021-07-19-etcd-learn/">go-etcd阅读笔记</a>
          </li>
        
          <li>
            <a href="/2021/07/28/2021/2021-06-22-go-ethereum-learn/">go-ethereum阅读笔记</a>
          </li>
        
          <li>
            <a href="/2021/07/28/2021/2021-06-21-server%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7/">server测试工具</a>
          </li>
        
          <li>
            <a href="/2021/07/28/2021/2021-06-09-pprof-doc/">go-pprof</a>
          </li>
        
          <li>
            <a href="/2021/07/28/2021/2021-04-19-c++-metaprogramming/">c++metaprogramming</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2021 Abel Sean<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  
<link rel="stylesheet" href="/fancybox/jquery.fancybox.css">

  
<script src="/fancybox/jquery.fancybox.pack.js"></script>




<script src="/js/script.js"></script>




  </div>
</body>
</html>